home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 101-125 / scopedisk109 / ms-dos / src / date.c next >
C/C++ Source or Header  |  1995-03-19  |  4KB  |  168 lines

  1. /*-
  2.  * $Id: date.c,v 1.2 90/02/03 17:00:25 Rhialto Exp $
  3.  * $Log:       date.c,v $
  4.  * Revision 1.2  90/02/03  17:00:25  Rhialto
  5.  * 0x21 -> DATE_MIN
  6.  * 
  7.  * Revision 1.1  89/12/17  20:03:37  Rhialto
  8.  * Initial revision
  9.  *
  10.  * DATE.C
  11.  *
  12.  * Two date conversion routines: DateStamp <-> MSDOS date/time.
  13.  *
  14.  * This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
  15.  * not be used or copied without a licence.
  16.  */
  17.  
  18. #include <libraries/dos.h>
  19. #include "han.h"
  20.  
  21. #define BASEYEAR           1978
  22. #define DAYS_PER_YEAR      365
  23. #define HOURS_PER_DAY      24
  24. #define MINUTES_PER_HOUR    60
  25. #define SECONDS_PER_MINUTE  60
  26.  
  27. #define DAYS_PER_WEEK      7
  28. #define MONTHS_PER_YEAR     12
  29.  
  30. #define MINUTES_PER_DAY     (MINUTES_PER_HOUR * HOURS_PER_DAY)
  31. #define SECONDS_PER_DAY     ((long) SECONDS_PER_MINUTE * \
  32.                             MINUTES_PER_HOUR * HOURS_PER_DAY)
  33.  
  34. #define LeapYear(year)  ((year & 3) == 0)   /* From 1-Mar-1901 to 28-Feb-2100 */
  35.  
  36. int daycount[MONTHS_PER_YEAR] = {
  37.        31,     28,    31,    30,    31,    30,
  38.        31,     31,    30,    31,    30,    31
  39. };
  40.  
  41. void
  42. ToDateStamp(datestamp, date, time)
  43. struct DateStamp *datestamp;
  44. word date;
  45. word time;
  46. {
  47.     {
  48.        int hours, minutes, seconds;
  49.  
  50.        seconds = (time & 31) * 2;
  51.        time >>= 5;
  52.        minutes = time & 63;
  53.        time >>= 6;
  54.        hours = time;
  55.  
  56.        datestamp->ds_Minute = MINUTES_PER_HOUR * hours + minutes;
  57.        datestamp->ds_Tick = TICKS_PER_SECOND * seconds;
  58.     }
  59.  
  60.     {
  61.        ulong i, j, t;
  62.        int year, month, day;
  63.  
  64.        if (date < DATE_MIN)
  65.            date = DATE_MIN;
  66.  
  67.        day = date & 31;
  68.        date >>= 5;
  69.        month = (date & 15) - 1;
  70.        date >>= 4;
  71.        year = date + 1980;
  72.  
  73.        if ((unsigned)month > 11 ||
  74.            (unsigned)day > (unsigned)daycount[month]) {
  75.            day = 31;
  76.            month = 11;
  77.            year = 1979;
  78.        }
  79.  
  80.        j = year - BASEYEAR;
  81.  
  82.        /* Get the next lower full leap period (4 years and a day) since ... */
  83.        t = (year - BASEYEAR) & ~3;
  84.        i = t;
  85.        t = (t / 4) * (4 * DAYS_PER_YEAR + 1);
  86.  
  87.        /* t now is the number of days in 4 whole years since ... */
  88.  
  89.        /*dbprintf(("ly0: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
  90.        while (i < j) {
  91.            /*dbprintf(("ly1: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
  92.            t += DAYS_PER_YEAR;
  93.            if (LeapYear(i + BASEYEAR)) {
  94.                /*dbprintf(("leap year\n"));*/
  95.                t++;
  96.            }
  97.            i++;
  98.        }
  99.  
  100.        /* t now is the number of days in whole years since ... */
  101.  
  102.        /*dbprintf(("m0:  i=%ld j=%ld t=%ld\n", i, j, t));*/
  103.        for (i = 0; i < month; i++) {
  104.            /*dbprintf(("m1: i=%ld j=%ld t=%ld\n", i, j, t));*/
  105.            t += daycount[i];
  106.            if (i == 1 && LeapYear(year)) {
  107.                t++;
  108.            }
  109.        }
  110.  
  111.        /* t now is the number of days in whole months since ... */
  112.  
  113.        t += day - 1;
  114.  
  115.        /* t now is the number of days in whole days since ... */
  116.  
  117.        datestamp->ds_Days = t;
  118.     }
  119. }
  120.  
  121. void
  122. ToMSDate(date, time, datestamp)
  123. word *date;
  124. word *time;
  125. register struct DateStamp *datestamp;
  126. {
  127.     {
  128.        word hours, minutes, seconds;
  129.  
  130.        hours = datestamp->ds_Minute / MINUTES_PER_HOUR;
  131.        minutes = datestamp->ds_Minute % MINUTES_PER_HOUR;
  132.        seconds = datestamp->ds_Tick / TICKS_PER_SECOND;
  133.  
  134.        *time = (hours << 11) | (minutes << 5) | (seconds / 2);
  135.     }
  136.     {
  137.        register long days, i, t;
  138.        int year, month, day;
  139.  
  140.        days = datestamp->ds_Days;
  141.  
  142.        year = BASEYEAR + (days/(4*DAYS_PER_YEAR+1)) * 4;
  143.        days %= 4 * DAYS_PER_YEAR + 1;
  144.        while (days) {
  145.                t = DAYS_PER_YEAR;
  146.                if (LeapYear(year))
  147.                        t++;
  148.                if (days < t)
  149.                        break;
  150.                days -= t;
  151.                year++;
  152.        }
  153.        days++;
  154.        for (i = 0; i < MONTHS_PER_YEAR; i++) {
  155.                t = daycount[i];
  156.                if (i == 1 && LeapYear(year))
  157.                        t++;
  158.                if (days <= t)
  159.                        break;
  160.                days -= t;
  161.        }
  162.        month = i + 1;
  163.        day = days;
  164.  
  165.        *date = ((year - 1980) << 9) | (month << 5) | day;
  166.     }
  167. }
  168.